(in-package #:org.shirakumo.fraf.trial.examples)

(define-shader-entity bouncer (listener vertex-entity colored-entity transformed-entity textured-entity)
  ((texture :initform (// 'trial 'trial::logo))
   (vertex-array :initform (// 'trial 'unit-square))
   (velocity :initform (vec 1 1 0) :accessor velocity)
   (color :initform (vec4 1))))

(define-handler (bouncer tick) (dt)
  (let ((loc (location bouncer))
        (vel (velocity bouncer))
        (w (* 0.5 (vx (scaling bouncer))))
        (h (* 0.5 (vy (scaling bouncer)))))
    (nv+* loc vel (* 100 dt))
    (flet ((rotate-color ()
             (let* ((colors #(#.(vec 1 0 0 1) #.(vec 0 1 0 1) #.(vec 0 0 1 1)
                              #.(vec 1 1 0 1) #.(vec 0 1 1 1) #.(vec 1 0 1 1)
                              #.(vec 1 1 1 1)))
                    (i (mod (1+ (or (position (color bouncer) colors) 0)) (length colors))))
               (setf (slot-value bouncer 'color) (aref colors i)))))
      (when (< (vx loc) w)
        (setf (vx loc) w)
        (setf (vx vel) (- (vx vel)))
        (rotate-color))
      (when (< (- (width *context*) w) (vx loc))
        (setf (vx loc) (- (width *context*) w))
        (setf (vx vel) (- (vx vel)))
        (rotate-color))
      (when (< (vy loc) h)
        (setf (vy loc) h)
        (setf (vy vel) (- (vy vel)))
        (rotate-color))
      (when (< (- (height *context*) h) (vy loc))
        (setf (vy loc) (- (height *context*) h))
        (setf (vy vel) (- (vy vel)))
        (rotate-color)))))

(define-example bouncer
  :title "DVD Bouncer"
  :description "An example recreating the infamous DVD logo bouncer"
  (enter (make-instance '2d-camera) scene)
  (enter (make-instance 'bouncer :scaling (vec 200 200 1)) scene)
  (enter (make-instance 'render-pass) scene))
